<?php

class StringSlicer
{
	public static function Slice( $String, $Piece_Length = 4 )
	{
		$Length = strlen( $String );
		if( $Length > 200 ) throw new Exception ( '200 characters erxceeded.' ); 
		$Parts = array( );
		for( $PartPosition = 0; $PartPosition < $Length; $PartPosition = $PartPosition + $Piece_Length )
		{
			$PartLength = $Length > $PartPosition + $Piece_Length ? $Piece_Length : $Length - $PartPosition;
			$Parts[] = substr( $String, $PartPosition, $PartLength );
		}
		return $Parts;
	}
}

class FileStorage
{
	// miliseconds, enter 0 for unlimited
	public static $LifeTime = 2592000; // 60 * 60 * 24 * 30 = 30 days
	
	public $Folder;
	public function __construct( $Folder = '' )
	{
		$this->Folder = str_replace( '\\', '/', $Folder );
	}
	
	public function Save( $Data )
	{
		$Key = $this->GetUniqueKey( );
		$this->CreateFolders( $Key );
		$Path = $this->GetPath( $Key );
		file_put_contents($Path, $Data);
		return $Key;
	}
	
	public function Overwrite( $Key, $Data )
	{
		$this->CreateFolders( $Key );
		$Path = $this->GetPath( $Key );
		file_put_contents($Path, $Data);
	}
	
	public function Move( $FilePath )
	{
		$Key = $this->GetUniqueKey( );
		$this->CreateFolders( $Key );
		$Path = $this->GetPath( $Key );
		move_uploaded_file( $FilePath, $Path );
		return $Key;
	}
	
	public function Load( $Key )
	{
		$Path = $this->GetPath( $Key );
		$Data = file_get_contents( $Path );
		return $Data;
	}
	
	public function Delete( $Key )
	{
		$Path = $this->GetPath( $Key );
		unlink( $Path );
	}
	
	public function GetPath( $Key )
	{
		$Parts = StringSlicer::Slice( $Key );
		$Path = $this->Folder == '' ? '' : $this->Folder . '/';
		$Path .= implode( '/', $Parts );
		return $Path;
	}
	
	public function GetSize( $Key )
	{
		$Path = $this->GetPath( $Key );
		return filesize( $Path );
	}
	
	public function IsValid( $Key )
	{
		$Path = $this->GetPath( $Key );
		return file_exists( $Path ) && 
			(time( ) - filemtime( $Path ) <= self::$LifeTime || self::$LifeTime == 0 );
	}
	
	public function IsUnique( $Key )
	{
		return !$this->IsValid( $Key );
	}




	
	
	
	
	public function GetParts( $Key )
	{
		$Length = strlen( $Key );
		$Parts = array( );
		for( $PartPosition = 0; $PartPosition < $Length; $PartPosition = $PartPosition + 4 )
		{
			$PartLength = $Length > $PartPosition + 4 ? 4 : $Length - $PartPosition;
			$Parts[] = substr( $Key, $PartPosition, $PartLength );
		}
		return $Parts;
	}
	
	public function GetUniqueKey( )
	{
		$Key = RandomGenerator::GetString( 32 );
		return $this->IsUnique( $Key ) ? $Key : $this->GetUniqueKey( );
	}
	
	public function CreateFolders( $Key )
	{
		$Path = $this->GetPath( $Key );
		$Parts = explode( '/', $Path );
		if( count( $Parts ) < 2 ) return;
		$PartialPath = $Parts[0];
		for( $i = 1; $i < count( $Parts ) - 1; ++$i)
		{
			$PartialPath .= '/' . $Parts[$i];
			if( !is_dir( $PartialPath ))
			{
				mkdir( $PartialPath );
			}
		}
	}
}

?>